function [Problem, C, S] = ProblemGenerator(param)
%  Generate synthetic examples
%    param:  parameters
%    Problem: returns the synthetic example

n = param.n;        
m = param.m;
Problem.param   = param;

% Generate the ground truth
Problem.x_gt    = randi( m, [n,1] ); 

[C, S] = Generate_Data_Cyclic(n, m, param.p_obs, param.pi0, Problem.x_gt);

% Matrix/vector representation of the truth
for i = 1: n 
    rowIdx = ((i-1)*m + 1) : (i*m);
    Problem.X_gt( rowIdx, : ) = circshift( eye(m),  Problem.x_gt(i)); 
end

% Compute the input data matrix L
Problem.L = generate_input(Problem.x_gt, param);




function [L0] = generate_input(x_gt, param)
% Generate the input matrix L (as a sparse matrix)
%   x_gt:  ground truth
%   param: input parameters

n       = param.n;  
m       = param.m;  
p_obs   = param.p_obs;
P0      = param.P0 / sum( param.P0 );
Pcs     = cumsum(P0);   
   
% Omega is the index set of the sampled pairs
Omega = zeros(n,n);
for i = 1: n
    for j = (i+1): n
        if rand() < p_obs,  Omega(i,j) = 1; end
    end
end

[rowsOmega, colsOmega] = find(Omega);
nSamples   = length(rowsOmega);
L0entries  = ones( nSamples*m, 2);

% Store the indices of nonzero entries for all cyclic permutation matrices
Eye_all_idx = zeros(m,2,m);
for i = 1: m
   [row_idx, col_idx] = find( circshift( eye(m), i-1) ); 
   Eye_all_idx(:, 1, i) = row_idx;
   Eye_all_idx(:, 2, i) = col_idx;
end

% Generate all non-zero entries of L
for l = 1: nSamples
    row_idx = ((l-1)*m+1) : (l*m);
    off  = min( find( Pcs > rand() ) ) - 1 ; 
    meas = mod( x_gt(rowsOmega(l)) - x_gt(colsOmega(l)) + off, m);
    
    % the starting points of the block (minus 1 in each dimensino)
    row_min = ( rowsOmega(l) -1 ) * m; 
    col_min = ( colsOmega(l) -1 ) * m;    
    L0entries( row_idx, 1:2 ) = repmat([row_min, col_min], [m,1]) + Eye_all_idx(:, :, meas + 1);
end

% Generate L0 as a sparse matrix
L0 = sparse(L0entries(:,1), L0entries(:,2), ones(nSamples*m,1), n*m, n*m);
L0 = L0 + L0';